package com.eight.cloud.generator.utils;

import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.eight.cloud.mybatisplus.entity.TenantDataScopeEntity;
import lombok.Data;
import lombok.experimental.Accessors;
import org.apache.ibatis.type.JdbcType;

import java.util.Collections;

/**
 * 代码生成器
 *
 * @ClassName: MyBatisPlusGenerator
 * @Author: TXC
 * @Date: 2024-11-05 14:20
 **/
@Data
public class MyBatisPlusGenerator {
    /**
     * 数据库ip加端口
     */
    private String dbHost;
    /**
     * 数据库名
     */
    private String dbName;
    /**
     * 数据库用户名
     */
    private String username;
    /**
     * 数据库密码
     */
    private String password;
    /**
     * 作者
     */
    private String author;
    /**
     * 父包名
     */
    private String parent;
    /**
     * 父包模块名
     */
    private String moduleName;
    /**
     * 项目根目录
     */
    private String dir = "D://generate";
    /**
     * 表名列表  支持正则匹配 如: "^sys_admin_.*"
     */
    private String[] tableInclude;
    /**
     * 过滤表前缀
     */
    private String tablePrefix;
    /**
     * 父类实体
     */
    private Class<?> superEntity;

    public MyBatisPlusGenerator(String dbHost, String dbName, String username, String password, String author,
                                String parent, String moduleName, String dir, String[] tableInclude,
                                String tablePrefix, Class<?> superEntity) {
        this.dbHost = dbHost;
        this.dbName = dbName;
        this.username = username;
        this.password = password;
        this.author = author;
        this.parent = parent;
        this.moduleName = moduleName;
        this.dir = dir;
        this.tableInclude = tableInclude;
        this.tablePrefix = tablePrefix;
        this.superEntity = superEntity;
    }

    public void generate() {
        String url = "jdbc:mysql://" + dbHost + "/" + dbName + "?allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai";
        FastAutoGenerator.create(url, username, password)
                // 全局设置
                .globalConfig(builder -> {
                    builder.author(author) // 设置作者
                            .dateType(DateType.TIME_PACK) // 设置时间类型策略
                            .commentDate("yyyy-MM-dd HH:mm")
                            .disableOpenDir() // 关闭自动打开文件夹
                            .outputDir(dir + "//src//main//java"); // 指定输出目录
                })
                // 数据库设置
                .dataSourceConfig(builder ->
                        builder.typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> {
                            // 兼容旧版本转换成Integer
                            if (JdbcType.TINYINT == metaInfo.getJdbcType()) {
                                return DbColumnType.INTEGER;
                            }
                            return typeRegistry.getColumnType(metaInfo);
                        })
                )
                //包设置，设置代码生成后的包名
                .packageConfig(builder ->
                        builder.parent(parent) // 设置父包名
                                .moduleName(moduleName) // 设置父包模块
                                .pathInfo(Collections.singletonMap(OutputFile.xml, dir + "//src//main//resources//mapper"
                                )) // 设置mapperXml生成路径
                )
                // 设置生成策略
                .strategyConfig(builder -> {
                    builder.addInclude(tableInclude) // 设置需要生成的表名
                            .addTablePrefix(tablePrefix) // 设置过滤表前缀
                            .enableSkipView().build();// 跳过视图
                            GeneratorUtils.entityStrategyConfig(builder, superEntity);
                            GeneratorUtils.mapperStrategyConfig(builder);
                            GeneratorUtils.serviceStrategyConfig(builder);
                            GeneratorUtils.controllerStrategyConfig(builder);
                        })
                .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板，默认的是Velocity引擎模板
                .execute();
    }

    @Data
    @Accessors(chain = true)
    public static class Builder {
        /**
         * 数据库ip加端口
         */
        private String dbHost = "localhost:3306";
        /**
         * 数据库名
         */
        private String dbName;
        /**
         * 数据库用户名
         */
        private String username;
        /**
         * 数据库密码
         */
        private String password;
        /**
         * 作者
         */
        private String author = "author";
        /**
         * 父包名
         */
        private String parent = "com.cloud.foundation";
        /**
         * 父包模块名
         */
        private String moduleName = "generate";
        /**
         * 项目根目录
         */
        private String dir = "D://generate";
        /**
         * 表名列表  支持正则匹配 如: "^sys_admin_.*"
         */
        private String[] tableInclude;
        /**
         * 过滤表前缀
         */
        private String tablePrefix;

        /**
         * 父类实体
         */
        private Class<?> superEntity = TenantDataScopeEntity.class;

        public Builder setTableInclude(String... tableInclude) {
            this.tableInclude = tableInclude;
            return this;
        }

        public Builder() {
        }

        public MyBatisPlusGenerator build() {
            return new MyBatisPlusGenerator(dbHost, dbName, username, password, author,
                    parent, moduleName, dir, tableInclude,
                    tablePrefix, superEntity);
        }

    }
}
